﻿using System;
using System.Text;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

using LeanEngine.Data.Linq.Language;

namespace LeanEngine.Data.Linq.Translator
{
    internal sealed class FromTranslator : LinqTranslator<FromToken>
    {
        #region Declaration Members

        private FromToken _token;

        #endregion

        #region LinqTranslator<FromToken> Members

        internal override bool CanEvaluate(QueryContext context)
        {
            throw new NotSupportedException();
        }

        internal override FromToken Interpret(QueryContext context)
        {
            var constant = GetConstant(context.LinqExpression as MethodCallExpression);
            if (constant == null) throw new Mapping.MappingException("Could not found the queryable table at linq expression.");

            _token = new FromToken();
            var table = constant.Value as IQueryableTable;
            _token.Table = new TableToken(table.MetaTable);
            
            return _token;
        }

        internal FromToken Interpret(ConstantExpression constant)
        {
            _token = new FromToken();
            var table = constant.Value as IQueryableTable;
            _token.Table = new TableToken(table.MetaTable);

            return _token;
        }

        #endregion

        #region Overrided Method Members
        #endregion

        #region Method Members

        private static ConstantExpression GetConstant(MethodCallExpression methodCall)
        {
            // recurse down all the method calls to find the source object
            while (true)
            {
                var argumentMethodCall = methodCall.Arguments[0] as MethodCallExpression;
                if (argumentMethodCall == null)
                {
                    break;
                }
                else
                {
                    methodCall = argumentMethodCall;
                }
            }

            return methodCall.Arguments[0] as ConstantExpression;
        }

        #endregion
    }
}
